//
// Copyright (C) [2024] Xingyun Integrated Circuit, Inc.
//
// GreenCode was a private technology asset of Xingyun Integrated Circuit， Inc （Confidential）
//  Author: Shawn.Tan
//  Date : 2025.10.28
//
//  History : Initial Version 2025.10.28
//
//
#include "InstructionConstraint.h"

#include "Choices.h"
#include "ChoicesModerator.h"
#include "Constraint.h"
#include "GenException.h"
#include "GenRequest.h"
#include "Generator.h"
#include "Instruction.h"
#include "InstructionStructure.h"
#include "Log.h"
#include "Operand.h"
#include "ResourceDependence.h"

using namespace std;

namespace Green {

  InstructionConstraint::InstructionConstraint(const InstructionConstraint& rOther)
    : mpInstructionRequest(rOther.mpInstructionRequest), mpHotResource(rOther.mpHotResource)
  {
    LOG(fail) << "InstructionConstraint copy constructor not meant to be called." << endl;
    FAIL("calling-instruction-constraint-copy-constructor-unexpectedly");
  }

  InstructionConstraint::~InstructionConstraint()
  {
    mpInstructionRequest = nullptr;
    delete mpHotResource; // delete if not null
  }

  void InstructionConstraint::Setup(const Generator& gen, const Instruction& instr, const InstructionStructure& instructionStruct)
  {
    mpHotResource = gen.GetDependenceInstance()->CreateHotResource();
  }

  BranchInstructionConstraint::~BranchInstructionConstraint()
  {
    mpBranchOperand = nullptr;
  }

  void BranchInstructionConstraint::Setup(const Generator& gen, const Instruction& instr, const InstructionStructure& instructionStruct)
  {
    InstructionConstraint::Setup(gen, instr, instructionStruct);
    mpBranchOperand = instr.FindOperandType<BranchOperand>();
    if (nullptr == mpBranchOperand) {
      LOG(fail) << "{BranchInstructionConstraint::Setup} BranchOperand not found." << endl;
      FAIL("branch-operand-not-found");
    }
  }

  BranchInstructionConstraint::BranchInstructionConstraint(const BranchInstructionConstraint& rOther)
    : InstructionConstraint(rOther), mpBranchOperand(nullptr)
  {

  }

  LoadStoreInstructionConstraint::~LoadStoreInstructionConstraint()
  {
    mpLoadStoreOperand = nullptr;
  }

  void LoadStoreInstructionConstraint::Setup(const Generator& gen, const Instruction& instr, const InstructionStructure& instructionStruct)
  {
    InstructionConstraint::Setup(gen, instr, instructionStruct);
    mpLoadStoreOperand = instr.FindOperandType<LoadStoreOperand>();
    if (nullptr == mpLoadStoreOperand) {
      LOG(fail) << "{LoadStoreInstructionConstraint::Setup} LoadStoreOperand not found." << endl;
      FAIL("load-store-operand-not-found");
    }
  }

  LoadStoreInstructionConstraint::LoadStoreInstructionConstraint(const LoadStoreInstructionConstraint& rOther)
    : InstructionConstraint(rOther), mpLoadStoreOperand(nullptr)
  {

  }

}
